﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Linq;
using System.Diagnostics;
using System.Threading;

namespace Chat
{
    public class ChatService
    {
        public static void Say(string message)
        {
            message = string.Concat("SAY,", message);
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            SaidByContext(message);
            stopwatch.Stop();
            Console.WriteLine($"Say 耗时:{stopwatch.ElapsedMilliseconds}ms");
        }

        private static void SaidByContext(string message)
        {
            ChatUser user = null;
            for (int i = 0; i < 1000; i++)
            {
                string userId = CallContext.GetData("UserId") as string;
                ChatMessage.Histories.Add(new ChatMessage()
                {
                    UserId = userId
                        ,
                    Message = message
                        ,
                    SendDate = DateTime.Now
                });
                user = ChatUser.OnlineUsers.FirstOrDefault(x => x.Id == userId);
            }
            Console.WriteLine($"{user} at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} said:{Environment.NewLine}{message}");
        }

        internal static void SayTo(string message,ChatUser to)
        {
            int waitSeconds = new Random().Next(10, 1000);
            ChatUser user = GetChatUser();
            Thread.Sleep(waitSeconds);
            user = GetChatUser();
            Console.WriteLine($"{user} waited {waitSeconds}s");
            Console.WriteLine($"at {DateTime.Now.ToString("HH:mm:ss.fff")} said {message} to {to}");
        }

        static string GetUserId()
        {
            return CallContext.GetData("UserId") as string;
        }

        static ChatUser GetChatUser()
        {
            string userId = GetUserId();
            return ChatUser.OnlineUsers.FirstOrDefault(x => x.Id == userId);
        }

        public static async Task Say(string message, string userId)
        {
            message = string.Concat("SAY2,", message);
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            await SaidByParameter(message, userId);
            stopwatch.Stop();
            Console.WriteLine($"Say2 耗时:{stopwatch.ElapsedMilliseconds}ms");
        }

        private static async Task SaidByParameter(string message, string userId)
        {
            await Task.Run(() =>
            {
                ChatUser user = null;
                for (int i = 0; i < 1000; i++)
                {
                    ChatMessage.Histories.Add(new ChatMessage()
                    {
                        UserId = userId
                                    ,
                        Message = message
                                    ,
                        SendDate = DateTime.Now
                    });
                    user= ChatUser.OnlineUsers.FirstOrDefault(x => x.Id == userId);
                }
                Console.WriteLine($"{user} at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} said:{Environment.NewLine}{message}");
            });
            

        }
    }
}
